package org.xurui.bsj.protocol.command.impl;

import lombok.extern.slf4j.Slf4j;
import org.jetlinks.core.message.CommonDeviceMessage;
import org.jetlinks.core.message.DeviceMessage;
import org.jetlinks.core.message.codec.EncodedMessage;
import org.jetlinks.core.message.codec.FromDeviceMessageContext;
import org.jetlinks.core.message.function.FunctionInvokeMessage;
import org.jetlinks.core.message.function.FunctionInvokeMessageReply;
import org.jetlinks.core.message.function.FunctionParameter;
import org.springframework.util.StringUtils;
import org.xurui.bsj.protocol.cache.ConcurrentMapCache;
import org.xurui.bsj.protocol.command.CmdCodec;
import org.xurui.bsj.protocol.enums.CommandEnum;
import org.xurui.bsj.protocol.msg.BsjMessage;
import org.xurui.bsj.protocol.msg.BsjMessageBuilder;
import org.xurui.bsj.protocol.utils.ArrayUtils;
import org.xurui.bsj.protocol.utils.BinaryUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 4.2.3.设置服务信息
 */
@Slf4j
public class CmdCodec_SET_HEALTH implements CmdCodec {
    @Override
    public boolean supportsCmd(String cmd) {
        return CommandEnum.SET_HEALTH.name().equals(cmd);
    }

    @Override
    public List<DeviceMessage> parsePayload(BsjMessage payload, FromDeviceMessageContext context) {
        //例子：[35380100360174,898600MFSSYYGXXXXXXP,201805082000001000, SET_HEALTH,2,20180528111820,1, 0@11@38.2]
        //例子2：[35380100360174,898600MFSSYYGXXXXXXP,201805082000001000, SET_HEALTH,2,20180528111820,1, 0@21@143]
        //例子3:[35380100360174,898600MFSSYYGXXXXXXP,201805082000001000, SET_HEALTH,2,20180528111820,1, 1@0@0]
        /**
         * 报文体格式： 成功失败标识
         *            @参数标识
         *            @参数上报
         * 例如： 0@21@38.2 标识温度测量请求成功上报温度 38.2 0@0@0 则表示设置成功 0@11@143#H120L80#95% 标识心率请求上报成功 心率 143 0@12@38.2!143#H120L80#95% 1 则表示请求失败或者设置失败
         */
        FunctionInvokeMessageReply report = FunctionInvokeMessageReply.create();
        report.setDeviceId(payload.getHeader().getDeviceNo());
        report.setFunctionId(payload.getHeader().getCmd());
        Object messageIdObj = ConcurrentMapCache.getInstance().getAndRemove(payload.getHeader().getOrderNo());
        String messageId = messageIdObj==null?null:messageIdObj.toString();
        if(messageId==null){
            messageId = payload.getHeader().getOrderNo();
        }
        report.setMessageId(messageId);
        report.setTimestamp(System.currentTimeMillis());
        Map<String, Object> properties = new HashMap<>();
        String tempBody = payload.getTempBody();
        String[] tempBodyArr = tempBody.split("@");
        //properties.put("header", FastBeanCopier.copy(payload.getHeader(), HashMap::new));
        properties.put("header", payload.getHeader().toMap());
        //成功失败标识
        properties.put("successFailBs", ArrayUtils.getStrByIndex(tempBodyArr,0));
        //参数标识
        properties.put("paramId",ArrayUtils.getStrByIndex(tempBodyArr,1));
        //参数上报
        properties.put("paramReport",ArrayUtils.getStrByIndex(tempBodyArr,2));
        report.setOutput(properties);
        return genDeviceMessage(report);
    }

    @Override
    public EncodedMessage encodeMessage(CommonDeviceMessage message,String zzs) {
        //平台下发消息
        //例子：[35380100360174,898600MFSSYYGXXXXXXP,201805082000001000, SET_HEALTH,1,20180528111820,2,10@1=0900!1200#2=1200@ ]
        //例子2：[35380100360174,898600MFSSYYGXXXXXXP,201805082000001000, SET_HEALTH,1,20180528111820,2,11@0@ ]
        /**
         * 报文体格式： 参数标识
         *            @参数@
         *            第一位:参数标识 10 心率/血压/血氧上报频率设置 11 获取实时心率/血压/血氧 20 温度上报频率设置 21 获取实时温度 12 获取实时温度和心率
         *            第二位:参数 例如： 1=0900!1200#2=1200 其中 0-6 标识星期， 0 表示星期日，1 表示星期一 6 标识星期六， 每天最多可设置 6 组定时测温或者心 率测试时间 每个时间点之间用！符分割，每天用# 分割获取实时数据时参数位补 0 温度保留一位小数
         */
        if(message instanceof FunctionInvokeMessage) {
            FunctionInvokeMessage m = (FunctionInvokeMessage) message;
            List<FunctionParameter> params = m.getInputs();
            Map<String, Object> paramsMap = params.stream()
                .collect(Collectors.toMap(FunctionParameter::getName, FunctionParameter::getValue));
            String  paramId="";
            if(paramsMap.get("paramId")!=null && !paramsMap.get("paramId").equals("")) {
                paramId=paramsMap.get("paramId").toString();
            }

            String param="";
            if(paramsMap.get("param")!=null && !paramsMap.get("param").equals("")) {
                param=paramsMap.get("param").toString();
            }

            if(StringUtils.isEmpty(paramId)){
                log.error("参数标识为空请重新填写");
                return null;
            }
            if(StringUtils.isEmpty(param)){
                log.error("参数为空请重新填写");
                return null;
            }
            StringBuffer sb = new StringBuffer();
            sb.append(paramId);
            sb.append(BinaryUtils.CMD_AT);
            sb.append(param);
            sb.append(BinaryUtils.CMD_AT);

            return BsjMessageBuilder.create().buildBsjFunctionInvoickMessage(m,sb.toString());
        }else{
            if (log.isDebugEnabled()) {
                log.debug("非FunctionInvokeMessage指令{}消息{}",CommandEnum.SET_HEALTH.name(),message);
            }
            return null;
        }

    }
}
